package com.zdya.combatdocuments.p2pNetwork;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zdya.combatdocuments.entity.*;
import com.zdya.combatdocuments.entity.vo.ResultEnum;
import com.zdya.combatdocuments.entity.vo.ResultVo;
import com.zdya.combatdocuments.mapper.NetworkMapper;
import com.zdya.combatdocuments.mapper.NetworkUserMapper;
import com.zdya.combatdocuments.util.ResultVoUtil;
import com.zdya.combatdocuments.util.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import springfox.documentation.spring.web.json.Json;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.OnMessage;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;

@Component
@Slf4j
public class P2pClient {
    @Autowired
    NodeUtil node;
    @Autowired
    HandleService handleService;
    @Autowired
    NetworkMapper networkMapper;
    @Autowired
    NetworkUserMapper networkUserMapper;


    public void connectPeer(String wsUrl){
        try{
            //创建websocket的客户端
            final WebSocketClient socketClient=new WebSocketClient(new URI(wsUrl)) {

                @Override
                public void onOpen(ServerHandshake serverHandshake) {
                    node.getNodeList().add(new Node(node.getIpByWs(this),this));
                    /**调用连接节点接口，发送user插入队列，返回对方user，插入队列*/
                    String str = JSONUtil.toJsonStr(node.getLocalUser());
                    User localUser = JSONUtil.toBean(str, User.class);
                    localUser.setId(null);
                    localUser.setKeystore(null);
                    localUser.setPrivateKey(null);
                    String ipAddress = node.getIpByWs(this);
                    String url = ipAddress+":"+node.getServerPort()+"/documents/network/changeUser";
                    String s = HttpUtil.post(url, JSONUtil.toJsonStr(localUser));
                    User result = JSONUtil.toBean(s, User.class);
                    node.getIp_keyList().add(result);
                    /**随后再进行type=8，插表+缓存队列+通知浏览器*/
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("type",8);
                    jsonObject.put("content", JSONUtil.toJsonStr(localUser));
                    node.write(this,jsonObject.toString());
                    log.info(node.getLocalIp()+"客户端向服务端"+node.getIpByWs(this)+"发送User信息");
                    log.info("信息:"+jsonObject.toString());
                }

                @Override
                public void onMessage(String msg) {
                    node.threadPool.submit(()->{
                        handleService.handleMessage(this,msg);
                    });

                }

                @Override
                @OnMessage(maxMessageSize=5242880)
                public void onMessage(ByteBuffer msg) {
                    node.threadPool.submit(()->{
                        handleService.handleMessage(this,msg);
                    });

                }

                @Override
                public synchronized void onClose(int i, String msg, boolean b) {
                    //判断来源，浏览器的话 删除并置空，主节点的话，循环关闭置空，其他的remove--list
                    String ipByWs = node.getIpByWs(this);
                    if(("127.0.0.1").equals(ipByWs)){
                        node.setBrowserClient(null);
                        node.client=null;
                        node.getNodeList().remove(new Node(node.getIpByWs(this),this));
                        log.info("浏览器关闭，关闭连接");
                    }else if ((ipByWs).equals(node.getPrimaryIp())) {
                        for (Node node:node.getNodeList()){
                            node.getWebSocket().close();
                        }
                        Network network = networkMapper.selectById(node.getNetworkId());
//                        network.setStatus(1);
                        networkMapper.updateById(network);
                        NetworkUser networkUser = networkUserMapper.selectOne(new QueryWrapper<NetworkUser>().eq("network_id", network.getId()).eq("user_id", node.getLocalUser().getId()));
                        networkUser.setStatus(1);
                        networkUserMapper.updateById(networkUser);
                        node.getNodeList().clear();
                        node.getIdToIpList().clear();
                        node.getUserList().clear();
                        node.getIp_keyList().clear();
                        log.info("主节点关闭，关闭连接");
                    }else {
                        node.getNodeList().remove(new Node(node.getIpByWs(this),this));
                        for(User user: node.getUserList()){
                            if (ipByWs == user.getIp() || (ipByWs).equals(user.getIp())){
                                node.getUserList().remove(user);
                                node.getIdToIpList().remove(new IdToIp(ipByWs,user.getId(),this));
                            }
                        }

                        log.info(ipByWs+"节点关闭，关闭连接");
                    }
                }

                @Override
                public void onError(Exception e) {
                    e.printStackTrace();
                       node.getNodeList().remove(new Node(node.getIpByWs(this),this));
                    log.info("connection failed");
                }
            };
            //客户端开始连接服务器
            socketClient.connect();
        }catch (URISyntaxException e){
            log.info("p2p connect is error:" + e.getMessage());
        }
    }
}
